package crivia.ecp.a;

import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

import crivia.c.CarryIO;
import crivia.c.a.AbstractCarry;
import crivia.c.a.KeyLink;
import crivia.c.carry.RelationKey;
import crivia.c.carry.ValueField;
import crivia.c.exception.CarryIOFail;
import crivia.db.exception.SQLMiss;
import crivia.eca.a.EcologyCMD;
import crivia.ecp.carry.tableString.TableSQL;
import crivia.ecp.common.EcologyDB;
import crivia.txt.exception.TextNotFound;
/**
 * Ecology Common Carry
 */
public abstract class ECC extends AbstractCarry {
	
	public final static String PK = "id";
	public String getId(){throw new crivia.c.exception.CarryIOFail("method [getId] is not implemented;");}
	public ECC setId(String id){throw new crivia.c.exception.CarryIOFail("method [setId] is not implemented;");}
	
	@Override
	@Deprecated
	public ValueField primaryKey() {
		return ValueField.c2d(PK);
	}
	
	public static boolean createTable(ECC c , boolean checkExist){
		EcologyCMD cmd = new EcologyCMD();
		if (checkExist && crivia.db.common.SQL.hasTable(c.tableName(), cmd)){
			return true;
		}
		String tSQL = 
			crivia.db.common.SQL.DataBaseType_SQL_Server.equals(cmd.DataBaseType()) 
				? c.createTableSQLServer().replaceAll("\t", " ").replaceAll("\n", " ")
			: crivia.db.common.SQL.DataBaseType_Oracle.equals(cmd.DataBaseType())
				? c.createTableOracle().replaceAll("\t", " ").replaceAll("\n", " ")
			: crivia.db.common.SQL.DataBaseType_MySQL.equals(cmd.DataBaseType())
				? c.createTableMySQL().replaceAll("\t", " ").replaceAll("\n", " ")
			: null;
		try {
			crivia.txt.common.Logger.log("Create Table SQL",tSQL);
		} catch (TextNotFound e) {}
		if (null == tSQL){
			throw new CarryIOFail("Unknow Data Base Type.");
		}

		java.sql.Connection n = EcologyDB.jdbc().connection();
		try {
			java.sql.PreparedStatement p = n.prepareStatement(tSQL);
			p.executeUpdate();
			return true;
		} catch (SQLException e) {
			try {
				crivia.txt.common.Logger.logException("Create Table Fail",e);
			} catch (Throwable ce) {}
			throw new SQLMiss(e);
		} finally {
			try {
				n.close();
			} catch (SQLException e) {
				throw new SQLMiss(e);
			}
		}
	}
	public static boolean createTable(Class<? extends ECC> c , boolean checkExist){
		return createTable(CarryIO.getInstance(c),checkExist);
	}

	public TableSQL simpleTableSQL(){
		return simpleTableSQL(new String[]{});
	}
	/**
	 * Setting Temp <b>Left Join Key</b> Like :
	 * <br>-----------------------------
	 * <br><b>new</b> Carry().simpleTableSQL(
	 * <br>&nbsp;&nbsp;&nbsp;&nbsp;Carry.<b>Keys</b>.<i>KeyName1</i>.key()
	 * <br>&nbsp;&nbsp;&nbsp;&nbsp;,Carry.<b>Keys</b>.<i>KeyName2</i>.key()
	 * <br>&nbsp;&nbsp;&nbsp;&nbsp;,Carry.<b>Keys</b>.<i>KeyName3</i>.key()
	 * <br>);
	 * <br>-----------------------------
	 **/
	@SuppressWarnings("deprecation")
	public TableSQL simpleTableSQL(String... leftJoinKeys){
		Set<String> leftJoinKeySet = new HashSet<String>();
		if (null != leftJoinKeys){
			for (String leftJoinKey : leftJoinKeys){
				leftJoinKeySet.add(leftJoinKey);
			}
		}
		StringBuilder field = new StringBuilder();
		StringBuilder from = new StringBuilder("from ")
			.append(tableName()).append(" t");
		boolean noPrimary = true;
		for (KeyLink keyLink : keyLinks()){
			if (keyLink instanceof RelationKey){
				if (field.length() > 0){
					field.append(",");
				}
				RelationKey r = (RelationKey) keyLink;
				if (leftJoinKeySet.contains(r.getKey())){
					r.relationTableType(RelationKey.RelationTableType.LeftJoin);
				}
				if (RelationKey.RelationTableType.LeftJoin
						.equals(r.relationTableType())){
					field.append(r.leftJoinSQLField())
						.append(" ").append(keyLink.getKey());
					from.append(r.leftJoinSQLTable("t"));
				} else if (RelationKey.RelationTableType.SubSelect
						.equals(r.relationTableType())){
					field.append(r.relationSQL("t"))
						.append(" ").append(keyLink.getKey());
				}
			} else if (! keyLink.outKey()) {
				if (field.length() > 0){
					field.append(",");
				}
				field.append("t.").append(keyLink.getKey_database());
				if (keyLink.getKey_database().toLowerCase().trim()
						.equals(primaryKey().getKey_database().toLowerCase().trim())){
					noPrimary = false;
				}
			}
		}
		if (noPrimary){
			field = new StringBuilder()
				.append("t.").append(primaryKey().getKey_database())
				.append(",").append(field);
		}
		String acec = "Auto_Carry_Empty_Column";
		field.append(", '' "+acec);
		
		return new TableSQL()
			.setField(field.toString())
			.setFrom(from.toString())
			.setOrderBy(acec)
			.setPk("t."+primaryKey().getKey_database());
	}
	
	
}
